package Concurrency2.Chapter05_Lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * Instruction：不可重入/可重入锁的自旋锁
 * Author：@author MaLi
 */
public class T05_SpinLock {
    private static class SpinLock implements Lock {
        private final AtomicReference<Thread> owner = new AtomicReference<>();

        /**
         * 实现逻辑分析:
         * 当前线程, 循环CAS改变owner
         * (1) 如果成功改变owner, 代表获取到锁;
         * (2) 否则, 继续尝试改变CAS修改owner, 失败之后出让CPU时间片,节省CPU资源.
         */
        @Override
        public void lock() {
            Thread currentThread = Thread.currentThread();
            // 可重入锁逻辑
            if (currentThread == owner.get())
                return;
            //不可重入锁逻辑
            while (!owner.compareAndSet(null, currentThread)) {
                Thread.yield(); //暂时出让CPU时间片, 防止CPU资源浪费
            }
        }

        /**
         * 实现逻辑分析:
         * 只有当前锁的拥有者可以释放锁
         * 如果owner属于当前Thread, 那么清空owner代表释放锁.
         */
        @Override
        public void unlock() {
            Thread currentThread = Thread.currentThread();
            //拥有者可以释放锁
            if (currentThread == owner.get()) {
                owner.set(null);
            }
        }

        @Override
        public void lockInterruptibly() throws InterruptedException {

        }

        @Override
        public boolean tryLock() {
            return false;
        }

        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            return false;
        }


        @Override
        public Condition newCondition() {
            return null;
        }
    }
}
